using System;
using System.Collections.Generic;

public enum AppleReceiptVerifyResult
{
    // 请求粗偶
    HttpRequestError,
    // 假的凭据
    FakeReceipt,
    // 成功
    Success,
}

public class AppStoreReceiptVerify 
{
    private bool m_SanBox;
    private string m_TransactionId;
    private string m_Receipt;

    private int m_RequestCount = 0;
    
    private Action<AppStoreReceiptVerify> m_OnResult;

    private AppleReceiptVerifyResult m_ResultStatus;
    private string m_HttpError;
    private string m_ResponseString;

    public string receipt => m_Receipt;
    
    public int requestCount => m_RequestCount;

    public AppleReceiptVerifyResult resultStatus => m_ResultStatus;
    public string httpError => m_HttpError;
    public string responseString => m_ResponseString;

    public Dictionary<string, object> responseJson;

    public int status = -1;// 支付状态
    public string environment; // 环境 Sandbox
    public string bundleId; // 程序包id
    public int quantity; // 购买的数量
    public string productId; // 商品id
    public DateTime receiptTime;
    
    public string transactionId => m_TransactionId; // 传入的订单号

    //{"status":21002}
    private const int status_error = 21002;

    public AppStoreReceiptVerify
    (
        bool sanbox, // 沙盒
        string transactionId,
        string receipt, // 收据
        Action<AppStoreReceiptVerify> callBack // 回调
        )
    {
        m_SanBox = sanbox;
        m_TransactionId = transactionId;
        m_Receipt = receipt;
        m_OnResult = callBack;
    }

    public void Verify()
    {
        // 增加一次请求次数
        ++m_RequestCount;
        
        string url = "https://buy.itunes.apple.com/verifyReceipt";
        if (m_SanBox)
        {
            url = "https://sandbox.itunes.apple.com/verifyReceipt";
        }
        
        GameDebug.Log($"Start Verify transactionId: {m_TransactionId}, receipt: {m_Receipt}");
        
        string json = $"{{\"receipt-data\":\"{m_Receipt}\"}}";
        
        AsyncHttpRequest webRequest = new AsyncHttpRequest(url);
        webRequest.onResponse = delegate(AsyncHttpRequest request)
        {
            GameDebug.Log($"AppleReceiptVerify error: {request.error}");
            GameDebug.Log($"AppleReceiptVerify response: {request.response}");

            m_HttpError = request.error;
            m_ResponseString = request.response;
            
            OnResult();
        };
        
        webRequest.POST(json);
    }

    private static readonly long ticks_1970 = new DateTime(1970, 1, 1).Ticks;
    /// <summary>
    /// 通过 purchase_date_ms 创建时间
    /// </summary>
    private static DateTime CreateFrom1970(long purchase_date_ms)
    {
        //"purchase_date": "2019-06-24 09:09:37 Etc/GMT",
        //"purchase_date_ms": "1561367377000",
        
        return new DateTime(ticks_1970 + purchase_date_ms * 10000);
    }
    /// <summary>
    /// 通过 purchase_date 创建时间
    /// </summary>
    private static DateTime CreateFrom1970(string purchase_date)
    {
        //"purchase_date": "2019-06-24 09:09:37 Etc/GMT",
        //"purchase_date_ms": "1561367377000",
        return DateTime.Parse(purchase_date.Replace("Etc/GMT", "").Trim());
    } 

    private void ParseResult ()
    {
        if (!string.IsNullOrEmpty(m_HttpError))
        {
            m_ResultStatus = AppleReceiptVerifyResult.HttpRequestError;
            return;
        }
        
        try
        {
            // {"status":21002} 常见加凭据
            if (m_ResponseString == "{\"status\":21002}")
            {
                m_ResultStatus = AppleReceiptVerifyResult.FakeReceipt;
                return;
            }

            Dictionary<string, object> json = MiniJSON.Json.Deserialize(m_ResponseString) as Dictionary<string, object>;
            if (json == null)
            {
                m_ResultStatus = AppleReceiptVerifyResult.FakeReceipt;
                return;
            }

            // status
            this.status = Convert.ToInt32(json["status"]);
            if (this.status == status_error)
            {
                m_ResultStatus = AppleReceiptVerifyResult.FakeReceipt;
                return;
            }

            // environment 正式环境有没有该字段？
            if (json.ContainsKey("environment"))
            {
                this.environment = (string)json["environment"];
            }

            // receipt
            Dictionary<string, object> receipt = json["receipt"] as Dictionary<string, object>;
            if (receipt == null)
            {
                GameDebug.LogError($"AppleReceiptVerify receipt parse null");
                m_ResultStatus = AppleReceiptVerifyResult.FakeReceipt;
                return;
            }
            
            // 收据创建时间
            string receipt_creation_date_ms = (string)receipt["receipt_creation_date_ms"];
            this.receiptTime = CreateFrom1970(Convert.ToInt64(receipt_creation_date_ms));
            
            // bundle_id
            this.bundleId = (string)receipt["bundle_id"];
            
            // in_app (* in_app 可能为空 *)
            List<object> in_app = receipt["in_app"] as List<object>;
            
            this.quantity = 0;
            this.productId = null;
            
            if (in_app == null)
            {
                //GameDebug.LogError($"AppleReceiptVerify in_app parse null");
                //m_ResultStatus = AppleReceiptVerifyResult.FakeReceipt;
            }
            else
            {
                for (int i = 0, count = in_app.Count; i < count; ++i)
                {
                    Dictionary<string, object> each_in_app = in_app[i] as Dictionary<string, object>;
                
                    // 通过传入的交易
                    string each_in_app_transaction_id = (string)each_in_app["transaction_id"];
                    if (each_in_app_transaction_id == m_TransactionId)
                    {
                        this.quantity = Convert.ToInt32(each_in_app["quantity"]);
                        this.productId = (string)each_in_app["product_id"];
                    
                        break;
                    }
                }
            }

            //if (this.productId == null)
            //{
            //    GameDebug.LogError($"AppleReceiptVerify productId not found");
            //    m_ResultStatus = AppleReceiptVerifyResult.FakeReceipt;
            //    return;
            //}

            m_ResultStatus = AppleReceiptVerifyResult.Success;
        }
        catch (Exception e)
        {
            GameDebug.LogError($"IAP 验证 解析出错{e}");
            m_ResultStatus = AppleReceiptVerifyResult.FakeReceipt;
        }
    }
    

    private void OnResult()
    {
        this.ParseResult();
        GameDebug.Log($"AppleReceiptVerify parse result status: {m_ResultStatus}");

        this.m_OnResult?.Invoke(this);
    }
}